package com.yonyou.brigade.facade.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.yonyou.brigade.basic_init.enums.ChannelEnum;
import com.yonyou.brigade.basic_init.enums.OpenTypeEnum;
import com.yonyou.brigade.basic_init.model.BriChannel;
import com.yonyou.brigade.basic_init.model.BriChannelAccount;
import com.yonyou.brigade.basic_init.model.RefModel;
import com.yonyou.brigade.basic_init.service.*;
import com.yonyou.brigade.facade.model.ChannelDTO;
import com.yonyou.brigade.facade.service.IAsyncService;
import com.yonyou.brigade.order_center.model.ThirdResult;
import com.yonyou.brigade.third_parties.bfjr.service.IBfjrDeptService;
import com.yonyou.brigade.third_parties.bfjr.service.IBfjrUserService;
import com.yonyou.brigade.third_parties.common.model.ThirdProperty;
import com.yonyou.brigade.third_parties.common.model.ThirdUser;
import com.yonyou.brigade.third_parties.common.service.IThirdPropertyService;
import com.yonyou.brigade.third_parties.ctripBC.model.CtripBCConfig;
import com.yonyou.brigade.third_parties.ctripBC.model.CtripBCUser;
import com.yonyou.brigade.third_parties.ctripBC.service.ICtripBCPublicService;
import com.yonyou.brigade.third_parties.ctripBC.util.CtripBCUserConvertUtil;
import com.yonyou.brigade.third_parties.fanscar.model.FanscarConfig;
import com.yonyou.brigade.third_parties.fanscar.model.FanscarJobGrade;
import com.yonyou.brigade.third_parties.fanscar.model.FanscarUser;
import com.yonyou.brigade.third_parties.fanscar.service.IFanscarDocService;
import com.yonyou.brigade.third_parties.fanscar.util.JobGradeConvertUtil;
import com.yonyou.brigade.third_parties.fanscar.util.UserConvertUtil;
import com.yonyou.brigade.third_parties.hcholiday.model.HcHolidayConfig;
import com.yonyou.brigade.third_parties.hcholiday.service.IHcHolidayUserService;
import com.yonyou.brigade.third_parties.hcholiday.util.HcHolidayUserUtil;
import com.yonyou.brigade.third_parties.huazhu.service.IHzUserService;
import com.yonyou.brigade.third_parties.meiya.model.MeiyaConfig;
import com.yonyou.brigade.third_parties.meiya.service.IMeiyaUserService;
import com.yonyou.brigade.third_parties.meiya.util.MeiyaUserConvertUtil;
import com.yonyou.brigade.third_parties.smectrip.model.CtripSmeUser;
import com.yonyou.brigade.third_parties.smectrip.service.ISmeCtripPublicService;
import com.yonyou.brigade.third_parties.smectrip.service.ISmeCtripUserService;
import com.yonyou.brigade.third_parties.tuniu.model.TnDeptHistory;
import com.yonyou.brigade.third_parties.tuniu.service.ITnDeptHistoryService;
import com.yonyou.brigade.third_parties.tuniu.service.ITuniuPublicService;
import com.yonyou.brigade.third_parties.yihao.service.ICLYHUserService;
import com.yonyou.brigade.third_parties.yihao.service.IYihaoDeptService;
import com.yonyou.brigade.util.mail.MailSenderUtil;
import com.yonyou.ybzboot.starter.common.exception.CustomException;
import com.yonyou.ybzboot.starter.mail.service.IMailService;
import com.yonyou.ybzboot.uc.dto.UcUserDto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 异步方法
 *
 * @author : kangfw5
 * @since 2019-03-01
 */
@Service
public class AsyncServiceImpl implements IAsyncService {
    private final static Logger logger = LoggerFactory.getLogger(AsyncServiceImpl.class);

    @Autowired
    private IFanscarDocService fanscarDocService;

    @Autowired
    @Qualifier(value = "briChannelServiceImpl")
    private IBriChannelService briChannelService;

    @Autowired
    @Qualifier("userCenterServiceImpl")
    private IUserCenterService userCenterService;

    @Autowired
    @Qualifier("baseDocServiceImpl")
    private IBaseDocService baseDocService;

    @Autowired
    @Qualifier("briChannelAccountServiceImpl")
    private IBriChannelAccountService briChannelAccountService;

    @Autowired
    @Qualifier("tnDeptHistoryServiceImpl")
    private ITnDeptHistoryService tnDeptHistoryService;

    @Autowired
    @Qualifier("tuniuPublicServiceImpl")
    private ITuniuPublicService tuniuPublicService;

    @Autowired
    @Qualifier("smeCtripPublicServiceImpl")
    private ISmeCtripPublicService smeCtripPublicService;

    @Autowired
    @Qualifier("smeCtripUserServiceImpl")
    private ISmeCtripUserService smeCtripUserService;

    @Autowired
    private IMeiyaUserService meiyaUserService;

    @Autowired
    private IThirdPropertyService thirdPropertyService;

    @Autowired
    private ICtripBCPublicService ctripBCPublicService;


    @Autowired
    private IHcHolidayUserService hcHolidayUserService;

    @Autowired
    @Qualifier("developerServiceImpl")
    private IDeveloperService developerService;

    @Autowired
    @Qualifier("mailServiceImpl")
    private IMailService mailService;

    @Autowired
    private IYihaoDeptService yihaoDeptService;

    @Autowired
    private ICLYHUserService iclyhUserService;

    @Autowired
    private IHzUserService hzUserService;

    @Autowired
    private IBfjrUserService bfjrUserService;

    @Autowired
    private IBfjrDeptService bfjrDeptService;


    /**
     * 同步档案信息
     *
     * @param channelDTO 开通信息
     * @author : kangfw5
     * @since 2019-03-01
     */
    @Override
    @Async
    public void syncDocInfo(ChannelDTO channelDTO) {
        String channel = channelDTO.getChannel();
        String tenant = channelDTO.getTenantId();
        Map configMap = channelDTO.getConfig();
        List<RefModel> orgs = channelDTO.getOrgs();
        logger.info("商旅开通异步执行开始");
        switch (channel) {
            case "fanscar":
                FanscarConfig fanscarConfig = JSON.parseObject(JSONObject.toJSONString(configMap), FanscarConfig.class);
                List<Map<String, String>> departmentList = new ArrayList<>();
                //  部门同步（最终取的是组织进行同步）
                if (!CollectionUtils.isEmpty(orgs)) {
                    for (RefModel refModel : orgs) {
                        Map<String, String> department = new HashMap<>(2);
                        department.put("DepartmentCode", refModel.getId());
                        department.put("DepartmentName", refModel.getName());
                        departmentList.add(department);
                    }
                }
                JSONArray errorResult = new JSONArray();
                if (BriChannel.SYNCORGDEPT == channelDTO.getSyncOrgDept()) {
                    errorResult = fanscarDocService.createDepartment(departmentList, fanscarConfig);
                } else {
                    logger.info("此租户：" + tenant + "的" + channel + "未配置同步部门");
                }
                // 职级同步
                if (BriChannel.SYNCRANK == channelDTO.getSyncRank()) {
                    List<FanscarJobGrade> fanscarJobGradeList = new ArrayList<>();
                    for (RefModel refModel : orgs) {
                        List<Map<String, String>> dutyList = baseDocService.getDutyByTenantAndOrg(tenant, refModel.getId());
                        fanscarJobGradeList.addAll(JobGradeConvertUtil.convertToFanscarJobGradeList(dutyList));
                    }
                    if (!CollectionUtils.isEmpty(fanscarJobGradeList)) {
                        JSONArray jobGradeErrorResult = fanscarDocService.createJobGrade(fanscarJobGradeList, fanscarConfig);
                        errorResult.addAll(jobGradeErrorResult);
                    }
                } else {
                    logger.info("此租户：" + tenant + "的" + channel + "未配置同步职级");
                }
                // 员工信息同步
                if (BriChannel.SYNCUSER == channelDTO.getSyncUser()) {
                    List<FanscarUser> fanscarUserList = new ArrayList<>();
                    for (RefModel refModel : orgs) {
                        List<UcUserDto> ucUserDtoList = userCenterService.getUcUserDtoByOrg(tenant, refModel.getId());
                        fanscarUserList.addAll(UserConvertUtil.convertToFanscarUserList(ucUserDtoList));
                    }
                    if (!CollectionUtils.isEmpty(fanscarUserList)) {
                        JSONArray userErrorResult = fanscarDocService.createEmployee(fanscarUserList, fanscarConfig);
                        errorResult.addAll(userErrorResult);
                    }
                } else {
                    logger.info("此租户：" + tenant + "的" + channel + "未配置同步人员");
                }
                if (errorResult.size() >= 1) {
                    String fanscarContent = "租户：" + tenant + ",组织：" + orgs + "开通错误信息：" + errorResult;
                    MailSenderUtil.sendCommonMail(developerService.listEmailByType("YY"), "泛嘉商旅开通提醒", fanscarContent);
                }
                break;
            case "ctripBC":
                BriChannel briChannel2 = new BriChannel();
                if (OpenTypeEnum.TENTANT.getIndex() == channelDTO.getOpenType()) {
                    briChannel2 = briChannelService.getEnableChannelByOpenType(tenant, ChannelEnum.CTRIPBC.getName(), channelDTO.getOpenType());
                } else {
                    briChannel2 = briChannelService.getEnableInfoByTenantOrg(tenant, channelDTO.getOrgs().get(0).getId(), ChannelEnum.CTRIPBC.getName());
                }
                // 同步人员信息到携程
                if (BriChannel.SYNCUSER == channelDTO.getSyncUser()) {
                    ctripBCPublicService.syncAllUsersToCtripBC(tenant, briChannel2.getOrgpk(), briChannel2.getOpenType(), briChannel2);
                } else {
                    logger.info("此租户：" + tenant + "的" + channel + "未配置同步人员");
                }
                break;
            case "tuniu":
                if (BriChannel.SYNCORGDEPT == channelDTO.getSyncOrgDept()) {
                    if (!CollectionUtils.isEmpty(orgs)) {
                        for (RefModel refModel : orgs) {
                            Wrapper<TnDeptHistory> wrapper = new EntityWrapper<>();
                            wrapper.eq(TnDeptHistory.TENANT, tenant);
                            wrapper.eq(TnDeptHistory.ORGPK, refModel.getId());
                            wrapper.eq(TnDeptHistory.DEPT_LEVEL, 1);
                            List<TnDeptHistory> tnDeptHistories = tnDeptHistoryService.selectList(wrapper);
                            //绑定开通后初始化途牛部门信息
                            BriChannel briChannel1 = briChannelService.getEnableInfoByTenantOrg(tenant, refModel.getId(), channel);
                            if (CollectionUtils.isEmpty(tnDeptHistories)) {
                                tuniuPublicService.initDepart(briChannel1);
                            }
                        }
                    } else {
                        logger.info("此租户：" + tenant + "的" + channel + "开通时未传入组织信息");
                    }
                } else {
                    logger.info("此租户：" + tenant + "的" + channel + "未配置同步部门");
                }
                break;
            case "ctripSME":
                // 同步管理员
                UcUserDto ucUserDtoByPhone = userCenterService.getCompleteUcUserDtoByPhone(channelDTO.getAdminPhone(), tenant);
                if (ucUserDtoByPhone == null) {
                    throw new CustomException("用户中心中该用户不存在 ！ phone :" + channelDTO.getAdminPhone());
                }
                // 同步管理员信息
                CtripSmeUser ctripSmeUser = getCtripSMEUser(ucUserDtoByPhone, tenant);
                JSONArray memberInfoModelArray = new JSONArray();
                JSONObject memberInfoModel = new JSONObject();
                memberInfoModel.put("EmployeeID", ctripSmeUser.getEmployeeId());
                memberInfoModel.put("Name", ctripSmeUser.getName());
                memberInfoModel.put("Mobile", ctripSmeUser.getMobile());
                memberInfoModel.put("IsUsed", ctripSmeUser.getValid());
                memberInfoModel.put("IsManager", true);
                memberInfoModelArray.add(memberInfoModel);
                smeCtripPublicService.syncCtripSmeUsers(tenant, memberInfoModelArray, JSON.toJSONString(channelDTO.getConfig()));
                smeCtripUserService.insert(ctripSmeUser);
                break;
            case "meiya":
                if (BriChannel.SYNCUSER == channelDTO.getSyncUser()) {
                    MeiyaConfig meiyaConfig = JSON.parseObject(JSONObject.toJSONString(configMap), MeiyaConfig.class);
                    String companyId = meiyaConfig.getCompanyId();
                    // 员工信息同步
                    List<ThirdUser> meiyaUserList = new ArrayList<>();
                    for (RefModel refModel : orgs) {
                        List<UcUserDto> ucUserDtoList = userCenterService.getUcUserDtoByOrg(tenant, refModel.getId());
                        meiyaUserList.addAll(MeiyaUserConvertUtil.ucUser2Meiya(tenant, companyId, ucUserDtoList));
                    }
                    ThirdResult result = meiyaUserService.syncUsers(meiyaConfig, meiyaUserList, channelDTO.getBriChannel());
                    String meiyaContent = "租户：" + tenant + ",组织：" + orgs + "开通错误信息：" + JSON.toJSONString(result);
                    MailSenderUtil.sendCommonMail(developerService.listEmailByType("YY"), "美亚商旅开通同步信息提醒", meiyaContent);
                } else {
                    logger.info("此租户：" + tenant + "的" + channel + "未配置同步人员");
                }
                break;
            case "hcholiday":
                if (BriChannel.SYNCUSER == channelDTO.getSyncUser()) {
                    HcHolidayConfig hcHolidayConfig = JSON.parseObject(JSON.toJSONString(configMap), HcHolidayConfig.class);
                    //同步员工信息
                    List<ThirdUser> hcHolidayUserList = new ArrayList<>();
                    for (RefModel org : orgs) {
                        List<UcUserDto> ucUserDtoList = userCenterService.getUcUserDtoByOrg(tenant, org.getId());
                        hcHolidayUserList.addAll(HcHolidayUserUtil.ucUser2Hc(tenant, hcHolidayConfig.getCuicode(), ucUserDtoList));
                    }
                    ThirdResult hcResult = hcHolidayUserService.syncUsers(hcHolidayConfig, hcHolidayUserList);
                    String hcContent = "租户：" + tenant + ",组织：" + orgs + "开通错误信息：" + JSON.toJSONString(hcResult);
                    MailSenderUtil.sendCommonMail(developerService.listEmailByType("YY"), "花城开通同步信息提醒", hcContent);
                } else {
                    logger.info("此租户：" + tenant + "的" + channel + "未配置同步人员");
                }
                break;
            case "clyh":
                try{
                    if (BriChannel.SYNCORGDEPT == channelDTO.getSyncOrgDept()) {
                        //同步顶级部门
                        logger.info("开始同步顶级部门：" + JSONObject.toJSONString(configMap));
                        JSONObject config = new JSONObject(configMap);
                        yihaoDeptService.sysRootDept(tenant,config);
                    }
                    if (BriChannel.SYNCUSER == channelDTO.getSyncUser()) {
                        logger.info("开始同步用户和部门：" + JSONObject.toJSONString(configMap));
                        for (RefModel org : orgs) {
                            List<UcUserDto> ucUserDtoList = userCenterService.getUcUserDtoByOrg(tenant, org.getId());
                            BriChannel briChannel = new BriChannel();
                            String configStr = JSONObject.toJSONString(configMap);
                            briChannel.setConfig(configStr);
                            iclyhUserService.sysClyhUsers(tenant, org.getId(), ucUserDtoList, briChannel);
                        }
                    }
                }catch (Exception e){
                    e.printStackTrace();
                    logger.error("差旅壹号开通时同步顶级部门出错：" + e.getMessage());
                }
                break;
            case "huazhu":
                if (BriChannel.SYNCUSER == channelDTO.getSyncUser()) {
                    logger.info("开始同步华住酒店用户：" + JSONObject.toJSONString(configMap));
                    for (RefModel org : orgs) {
                        List<UcUserDto> ucUserDtoList = userCenterService.getUcUserDtoByOrg(tenant, org.getId());
                        BriChannel briChannel = new BriChannel();
                        String configStr = JSONObject.toJSONString(configMap);
                        briChannel.setConfig(configStr);
                        hzUserService.syncUserList(ucUserDtoList, briChannel, tenant);
                    }
                }

                break;


            case "bfjr":
                if (BriChannel.SYNCORGDEPT.intValue() == channelDTO.getSyncOrgDept().intValue()) {
                    logger.info("开始同步北方假日部门："+JSONObject.toJSONString(configMap));
                    UcUserDto userDto = userCenterService.getCompleteUcUserDtoByPhone(channelDTO.getAdminPhone(), tenant);
                    JSONObject config = new JSONObject(configMap);
                    if (userDto != null) {
                        bfjrDeptService.sysOrgDept(tenant,userDto.getOrgPk(), userDto.getOrgName(), config);
                    } else {
                        logger.info("getCompleteUcUserDtoByPhone,调用远程用户中心服务查询UcUserDto为空");
                    }
                }


                if (BriChannel.SYNCUSER.intValue() == channelDTO.getSyncUser().intValue()) {
                    logger.info("开始同步北方假日用户："+JSONObject.toJSONString(configMap));
                    for (RefModel org : orgs) {
                        List<UcUserDto> ucUserDtoList = userCenterService.getUcUserDtoByOrg(tenant, org.getId());
                        if (!CollectionUtils.isEmpty(ucUserDtoList)) {
                            BriChannel briChannel = new BriChannel();
                            String configStr = JSONObject.toJSONString(configMap);
                            briChannel.setConfig(configStr);
                            bfjrUserService.syncBfjrUserList(ucUserDtoList, briChannel, tenant);
                        } else {
                            logger.info("getUcUserDtoByOrg,调用远程用户中心服务查询ucUser为空,tenant:"+tenant+"orgId:"+org.getId());
                        }
                    }
                }
                break;
            default:
                break;
        }
    }

    @Override
    @Async
    public void syncDisableStaffByOrg(BriChannel briChannel, String tenant, String org) {
        switch (briChannel.getChannel()){
            case "clyh":
                iclyhUserService.disableUserByOrg(tenant, org, briChannel);
                break;
            default:
                break;
        }
    }



    /**
     * 用户中心的用户转化为写携程商旅通用户
     *
     * @param ucUserDto
     * @return
     */
    private CtripSmeUser getCtripSMEUser(UcUserDto ucUserDto, String tenant) {
        CtripSmeUser ctripSmeUser = new CtripSmeUser();
        ctripSmeUser.setTenant(tenant);
        ctripSmeUser.setOrg(ucUserDto.getOrgPk());
        ctripSmeUser.setUserId(ucUserDto.getUserId());
        ctripSmeUser.setBirthday(ucUserDto.getBirthday());
        ctripSmeUser.setDept1(ucUserDto.getOrgName());
        ctripSmeUser.setDept2(ucUserDto.getDeptName());
        ctripSmeUser.setEmployeeId(ucUserDto.getPersonCode());
        ctripSmeUser.setEmail(ucUserDto.getEmail());
        ctripSmeUser.setMobile(ucUserDto.getPhone());
        ctripSmeUser.setName(ucUserDto.getUserName());
        ctripSmeUser.setGender("0");
        ctripSmeUser.setHasBookingForOther(0);
        ctripSmeUser.setValid(ucUserDto.getDr() == 0 ? true : false);
        ctripSmeUser.setaManager(true);
        return ctripSmeUser;
    }
}
